package main

import (
	"embed"
	"encoding/hex"
	"flag"
	"openzbox.com/driver/net/canbus"
	"openzbox.com/frame/echo"
	"openzbox.com/frame/echo/middleware"
	"openzbox.com/gateway/api"
	"openzbox.com/gateway/core"
	"openzbox.com/log"
	"openzbox.com/misc/service"
	"openzbox.com/utils"
	"os"
	"strings"
)

//go:embed web/*
var webroot embed.FS

func recevedCAN() {

	sck, err := canbus.New()
	if err != nil {
		log.Error(err)
		return
	}
	defer sck.Close()

	addr := "can0"
	err = sck.Bind(addr)

	if err != nil {
		log.Fatalf("error binding to [%s]: %v\n", addr, err)
	}
	var blank = strings.Repeat(" ", 24)
	var temperature float32 = 0.0
	for {
		msg, err := sck.Recv()
		if err != nil {
			log.Fatalf("recv error: %v\n", err)
		}
		ascii := strings.ToUpper(hex.Dump(msg.Data))
		ascii = strings.TrimRight(strings.Replace(ascii, blank, "", -1), "\n")
		log.Infof("%s %08x %s", sck.Name(), msg.ID, ascii)

		if len(msg.Data) >= 4 {
			temperature = utils.ByteToFloat32([]byte{msg.Data[0], msg.Data[1], msg.Data[2], msg.Data[3]})
			log.Infof("temperature:%.02f", temperature)
		}
	}
}
func startIOTService() {

	//go core.StartNatsServer()

	//go core.StartNatsRelay()

	//初始化盒子配置
	core.Mybox = &core.Mbox{}
	core.InitBox(core.Mybox)

	//闪烁活动指示LED，1000毫秒间隔
	core.Mybox.OpenFaultLED(1000)
	//开启故障指示灯 500 毫秒间隔
	core.Mybox.OpenActiveLED(500)

	core.Mybox.Iamhere()
	go recevedCAN()

	// Echo instance
	e := echo.New()
	e.HideBanner = true

	// Middleware
	//e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// Routes

	//系统信息
	e.GET("/xapi/sysinfo", api.Sysinfo)
	e.GET("/xapi/dmesg", api.GetDmesg)
	//网络配置
	e.GET("/xapi/netfaces", api.GetNetInfo)

	//系统复位
	e.POST("/xapi/reboot", api.RebootSystem)
	//系统冷启动
	e.POST("/xapi/hardreboot", api.PorwerRebootSystem)
	//系统设置保存
	e.POST("/xapi/sysconfig", api.SaveConfig)
	e.GET("/xapi/sysconfig", api.GetConfig)
	//恢复出厂
	e.POST("/xapi/restore", api.RestoreFactory)

	//指令管理
	e.PUT("/xapi/command", api.NewCommand)
	e.GET("/xapi/command", api.ListCommand)
	e.GET("/xapi/command/:cmd_name", api.ListCommand)
	e.POST("/xapi/command/:cmd_name", api.UpdateCommand)
	e.DELETE("/xapi/command", api.DeleteCommand)
	//测试
	e.POST("/xapi/testcommand", api.TestCommand)

	//端口配置
	e.GET("/xapi/ports", api.ListPorts)         //列出所有端口
	e.GET("/xapi/ports/:name", api.GetPort)     //列出所有端口
	e.POST("/xapi/ports/:name", api.UpdatePort) //列出所有端口
	e.POST("/xapi/openport", api.OpenPort)      //打开所有端口
	e.POST("/xapi/closeport", api.ClosePort)    //关闭所有端口

	e.GET("/ws", api.WebSocketService)

	e.StaticFS("/", webroot, "web")

	//go core.StartModbusRTU()

	core.Mybox.CloseFaultLED()
	core.Mybox.CloseActiveLED()
	//go core.StartGotty();
	// Start server
	e.Logger.Fatal(e.Start(":80"))
}

type program struct{}

func (p *program) Start(s service.Service) error {
	// Start should not block. Do the actual work async.
	go p.run()
	return nil
}
func (p *program) run() {
	// Do work here
	startIOTService()
}
func (p *program) Stop(s service.Service) error {
	// Stop should not block. Return with a few seconds.
	return nil
}

func main() {
	svcFlag := flag.String("service", "start", "Control the openzbox gateway service.\r\nstart \r\nstop \r\nrestart  \r\ninstall \r\nuninstall\"")
	flag.Parse()

	svcConfig := &service.Config{
		Name:        "OpenZboxGW",
		DisplayName: "OpenZbox Gateway 1.1",
		Description: "This is an OpenZbox IOT Gateway Service.",
	}

	prg := &program{}
	s, err := service.New(prg, svcConfig)
	if err != nil {
		log.Fatal(err)
	}
	if len(os.Args) > 1 {
		err := service.Control(s, *svcFlag)
		if err != nil {
			//log.Fatal(err)
		}
		return
	}
	err = s.Run()
	if err != nil {
		log.Error(err)
	}
}
